home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir39
/
borfix.zip
/
TI1300.ASC
< prev
next >
Wrap
Text File
|
1993-10-25
|
9KB
|
397 lines
PRODUCT : Borland C++ NUMBER : 1300
VERSION : 3.x
OS : DOS
DATE : October 25, 1993 PAGE : 1/6
TITLE : Example of how to access expanded (EMS) memory.
/************************************************************
This program demonstrates the use of EMS (expanded memory.)
In this program, we use EMS to store a simulated array of
50,000 long ints. Compile in any memory model.
It is not optimized, for purposes of clarity.
Many thanks to Ray Duncan for his lucid exposition of
EMS in "Extending DOS"
************************************************************/
#include <fcntl.h>
#include <sys\stat.h>
#include <io.h>
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define EMS_INT 0x67
#define PAGESIZE 16384
int EMSHandle;
int pageMap[4] = { -1, -1, -1, -1 };
int pageFrame;
// Function to test for existence of EMS. If coding a TSR or
// ISR, you will be unable to call DOS and therefore must check
// if the name EMMXXXX0 is at offset 10 from the entrypoint to
// the EM Manager pointed to by vector 0x67
char EMSExists(void)
{
int handle,devInfo,outputStatus;
// The expanded memory manager if present should show up
// as a filename
if ((handle=open("EMMXXXX0",O_RDONLY|O_BINARY)) == -1)
return FALSE;
devInfo=ioctl(handle,0);
// if bit 7 is 0 it is a file
if ((devInfo & 0x80) == 0)
{
printf("Found File EMMXXXX0?!?\n");
PRODUCT : Borland C++ NUMBER : 1300
VERSION : 3.x
OS : DOS
DATE : October 25, 1993 PAGE : 2/6
TITLE : Example of how to access expanded (EMS) memory.
close(handle);
return FALSE;
}
outputStatus=ioctl(handle,7);
if (outputStatus==0)
{
printf("EMM present but not responding\n");
close(handle);
return FALSE;
}
// file handle for EMS manager is useless for anything
// further, so we'll just close it.
close(handle);
return TRUE;
}
// Assuming EMS is present, it may still not be functional
// due to a hardware error or who knows what, so we have
// a function to check whether the expanded memory manager
// is ready to do its business.
char EMSFunctional(void)
{
_AH=0x40;
geninterrupt(EMS_INT);
if (_AH==0) return FALSE;
else return TRUE;
}
// EMSSize() finds out the total and available pages of EMS
void EMSSize(int *pagesTotal, int *pagesAvail)
{
_AH=0x42;
geninterrupt(0x67);
*pagesAvail=_BX;
*pagesTotal=_DX;
}
// EMSAlloc() tries to allocate the number of pages corresponding
// to the size in bytes of the allocation requested.
char EMSAlloc(unsigned long bytes)
PRODUCT : Borland C++ NUMBER : 1300
VERSION : 3.x
OS : DOS
DATE : October 25, 1993 PAGE : 3/6
TITLE : Example of how to access expanded (EMS) memory.
{
int numPages;
numPages=(int) (bytes/PAGESIZE);
if (bytes%PAGESIZE != 0) ++numPages;
_BX=numPages;
_AH=0x43;
geninterrupt(EMS_INT);
EMSHandle=_DX;
if (_AH!=0)
{
printf("Allocation of %d pages failed\n",numPages);
return FALSE;
}
else
{
printf("Allocated %d pages\n",numPages);
return TRUE;
}
}
// CleanUp() tries to deallocate our EMS allocation
void CleanUp(void)
{
_AH=0x45;
_DX=EMSHandle;
geninterrupt(EMS_INT);
if (_AH!=0) printf("Deallocation failed!\n");
}
void EMSRemap(int logpage)
{
// the mapping scheme we're using is that the physical page
// mapping for a logical page is the logical page mod 4
printf("Mapping logical page %d\n",logpage);
// ask to map logical page _BX into physical page (0->3) _AL
_AL=logpage&3;
_BX=logpage;
_DX=EMSHandle;
_AH=0x44;
geninterrupt(EMS_INT);
if (_AH!=0)
{
PRODUCT : Borland C++ NUMBER : 1300
VERSION : 3.x
OS : DOS
DATE : October 25, 1993 PAGE : 4/6
TITLE : Example of how to access expanded (EMS) memory.
printf("Mapping failed!\n");
CleanUp();
exit(1);
}
pageMap[logpage&3]=logpage;
}
// GetEMSPageFrame finds the segment that the page frame lives
// at and stores it in pageFrame for use by PutVal and GetVal
void GetEMSPageFrame(void)
{
_AH=0x41;
geninterrupt(EMS_INT);
pageFrame=_BX;
if (_AH!=0)
{
printf("Cannot get page frame!\n");
CleanUp();
exit(1);
}
}
// PutVal() puts a value into the array, asking for a page to be
// remapped if the correct page isn't in memory.
// With both PutVal() and GetVal(), the code could be optimized
// considerably by using bitshifts instead of multiplies. And,
// a real application would probably be coded to check less
// often for the page being present.
void PutVal(unsigned long loc, unsigned long val)
{
unsigned int logPage; // logical page
unsigned long far * physLoc;
// loc*sizeof(long) is the byte address of the item; we
// divide by PAGESIZE to figure out which logical page
// it's on
logPage= (int) (loc*sizeof(long)/PAGESIZE);
// logical page mod 4 is our scheme to map a logical page
// to a physical page. pageMap tells us which logical
// page is being kept in each physical page.
PRODUCT : Borland C++ NUMBER : 1300
VERSION : 3.x
OS : DOS
DATE : October 25, 1993 PAGE : 5/6
TITLE : Example of how to access expanded (EMS) memory.
if (pageMap[logPage&3]!=logPage) EMSRemap(logPage);
// the offset in the EMS buffer will be sizeof(long) times
// the array index, mod 64K; the segment of the EMS buffer
// is of course pageFrame.
physLoc= (unsigned long far *)
MK_FP(pageFrame,(loc*sizeof(long))&65535U);
*physLoc=val;
}
// GetVal() gets a value from the 'array', asking for a page to
// be remapped if the correct page isn't in memory.
unsigned long GetVal(unsigned long loc)
{
unsigned int logPage;
unsigned long far * physLoc;
logPage= (int) (loc*sizeof(long)/PAGESIZE);
if (pageMap[logPage&3]!=logPage) EMSRemap(logPage);
physLoc= (unsigned long far *)
MK_FP(pageFrame,(loc*sizeof(long))&65535U);
return *physLoc;
}
int main(void)
{
int pagesAvail,pagesTotal;
unsigned long i;
if (EMSExists()) printf("Found EMS\n");
else
{
printf("No EMS");
return(1);
}
if (EMSFunctional) printf("EMS Working\n");
else
{
printf("EMS present but malfunctioning\n");
return(1);
}
EMSSize(&pagesTotal,&pagesAvail);
printf("EMS Pages -- Total: %u, Available %u (%uK)\n",
pagesTotal,pagesAvail,pagesAvail*16);
PRODUCT : Borland C++ NUMBER : 1300
VERSION : 3.x
OS : DOS
DATE : October 25, 1993 PAGE : 6/6
TITLE : Example of how to access expanded (EMS) memory.
// allocate enough space in EMS for 50,000 long ints
if (!EMSAlloc(sizeof(long)*50000L))
return(1);
GetEMSPageFrame();
printf("Page frame at segment 0x%4X\n",pageFrame);
// Test our EMS functions by storing and retrieving
// 50,000 long ints
for (i=0; i<50000L; ++i)
PutVal(i,i);
for (i=0; i<50000L; ++i)
if (GetVal(i)!=i)
{
printf("%d != %d\n",GetVal(i),i);
break;
}
CleanUp();
return(0);
}
DISCLAIMER: You have the right to use this technical information
subject to the terms of the No-Nonsense License Statement that
you received with the Borland product to which this information
pertains.